# -*- coding: utf-8 -*-
# @file    : __init__.py
# @Date    : 2020/10/21
# @Author  :
# @Version : 1.0.0
import asyncio
import threading

from pynput import keyboard as _keyboard

from .action import ActionGroup


class MacroThread(threading.Thread):
    """
    宏执行线程
    """

    def __init__(self):
        print("[宏执行线程]: 构建中...")
        super(MacroThread, self).__init__()
        self.loop = None

    def run(self):
        print("[宏执行线程]: 启动成功!")
        self.loop = asyncio.new_event_loop()
        self.loop.run_forever()

    def run_act_group(self, act_group):
        assert isinstance(act_group, ActionGroup), "不是有效的动作组"
        if act_group.running is True:
            return
        act_group.running = True
        coroutine = act_group()
        asyncio.run_coroutine_threadsafe(coroutine, self.loop)

    def stop_act_group(self, act_group):
        assert isinstance(act_group, ActionGroup), "不是有效的动作组"
        for task in asyncio.all_tasks(self.loop):
            stack = task.get_stack()
            if not stack:
                continue
            frame = stack.pop()
            if frame.f_locals['self'] == act_group:
                task.cancel()


class ListenerThread(_keyboard.GlobalHotKeys):
    """
    全局热键监听线程
    """

    def __init__(self, hotkeys: list):
        print("[全局热键监听线程]: 构建中...")
        super(ListenerThread, self).__init__({})
        for hk in hotkeys:
            assert isinstance(hk, HotKey), "不是有效的热键对象"
            self._hotkeys.append(hk)

    def run(self):
        print("[全局热键监听线程]: 启动成功!")
        return super(ListenerThread, self).run()


class HotKey(_keyboard.HotKey):
    """
    热键对象
    """

    def __init__(self, keys, on_activate):
        super().__init__(keys, on_activate)
        self.action_group = None
        self.activate_count = 0

    def press(self, key):
        if key in self._keys and key not in self._state:
            self._state.add(key)
            if self._state == self._keys:
                self.activate_count += 1
                self._on_activate(self)
